/**************************************************************
* Copyright (C) 2022 www.eipflow.com 孙泽伟版权所有(盗版必究)
*
* 作者: 孙泽伟(QQ 1039318332)
* 创建时间: 2018/11/9 9:21:04
* 文件名: 
* 描述: 
* 
* 修改历史
* 修改人：
* 时间：
* 修改说明：
*
**************************************************************/
using EIP.System.Models.Dtos.WorkSheet;
using SystemIo = System.IO;
namespace EIP.System.Logic.Impl
{
    /// <summary>
    /// 零代码业务逻辑接口实现
    /// </summary>
    public class SystemZeroCodeLogic : DapperAsyncLogic<SystemZeroCode>, ISystemZeroCodeLogic
    {
        #region 构造函数
        private readonly ISystemDictionaryLogic _dictionaryLogic;
        private readonly ISystemDataBaseRepository _dataBaseRepository;
        private readonly ISystemZeroCodeRepository _zeroCodeRepository;
        private readonly ISystemConfigLogic _systemConfigLogic;
        /// <summary>
        /// 模块
        /// </summary>
        /// <param name="zeroCodeRepository"></param>
        public SystemZeroCodeLogic(ISystemDictionaryLogic dictionaryLogic, ISystemZeroCodeRepository zeroCodeRepository, ISystemDataBaseRepository dataBaseRepository, ISystemConfigLogic systemConfigLogic)
        {
            _systemConfigLogic = systemConfigLogic;
            _zeroCodeRepository = zeroCodeRepository;
            _dataBaseRepository = dataBaseRepository;
            _dictionaryLogic = dictionaryLogic;
        }

        #endregion

        #region 方法

        /// <summary>
        /// 保存
        /// </summary>
        /// <param name="input">实体</param>
        /// <returns></returns>
        public async Task<OperateStatus> Save(SystemZeroCode input)
        {
            OperateStatus operateStatus = new OperateStatus();
            SystemZeroCode zeroCode = await FindAsync(f => f.ZeroCodeId == input.ZeroCodeId);
            var currentUser = EipHttpContext.CurrentUser();
            if (zeroCode == null)
            {
                input.CreateTime = DateTime.Now;
                input.CreateUserId = currentUser.UserId;
                input.CreateUserName = currentUser.Name;
                input.UpdateTime = DateTime.Now;
                input.UpdateUserId = currentUser.UserId;
                input.UpdateUserName = currentUser.Name;
                operateStatus = await InsertAsync(input);
                if(input.Type== EnumZeroCodeType.工作表.ToShort())
                {
                    //增加默认按钮
                }
            }
            else
            {
                zeroCode.OrderNo = input.OrderNo;
                zeroCode.Name = input.Name;
                zeroCode.IsFreeze = input.IsFreeze;
                zeroCode.Remark = input.Remark;
                zeroCode.UpdateTime = DateTime.Now;
                zeroCode.UpdateUserId = currentUser.UserId;
                zeroCode.UpdateUserName = currentUser.Name;

                operateStatus = await UpdateAsync(zeroCode);
            }
            if (operateStatus.Code == ResultCode.Success)
            {
                operateStatus.Msg = "保存成功";
            }
            return operateStatus;
        }

        /// <summary>
        /// 保存缩略图
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<OperateStatus> SaveThumbnail(SystemZeroCode input)
        {
            string hearderpath = "";
            var filePath = ConfigurationUtil.GetTempPath() + $"/{Guid.NewGuid()}.png";
            //转换并保存图片
            input.Thumbnail.ConvertBase64ToImage(filePath);
            var filesStorageOptions = (await _systemConfigLogic.FindFilesStorageOptions()).Data;
            var FileBytes = SystemIo.File.ReadAllBytes(filePath);
            using (var ms = new SystemIo.MemoryStream(FileBytes))
            {
                IFormFile file = new FormFile(ms, 0, ms.Length,
                    SystemIo.Path.GetFileNameWithoutExtension(filePath),
                    SystemIo.Path.GetFileName(filePath));
                var fileName = file.FileName;
                var fileExt = SystemIo.Path.GetExtension(fileName).ToLowerInvariant();
                OssUtil ossUtil = new OssUtil();
                hearderpath = await ossUtil.UpLoadFile(filesStorageOptions, fileExt, file);
                //删除临时文件
                FileUtil.DeleteFile(filePath);
            }
            return await UpdateAsync(u => u.ZeroCodeId == input.ZeroCodeId, new { Thumbnail = hearderpath, UpdateTime = DateTime.Now });
        }

        /// <summary>
        /// 发布
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<OperateStatus> PublicJson(SystemZeroCode input)
        {
            var zeroCode = await FindAsync(u => u.ZeroCodeId == input.ZeroCodeId);
            zeroCode.PublicJson = input.PublicJson;
            zeroCode.ColumnJson = input.ColumnJson;
            await SaveOptionsToDictionary(zeroCode);
            return await UpdateAsync(u => u.ZeroCodeId == input.ZeroCodeId, new { PublicJson = input.PublicJson, ColumnJson = input.ColumnJson, UpdateTime = DateTime.Now });
        }
        /// <summary>
        /// 选项保存到字典
        /// </summary>
        /// <returns></returns>
        private async Task<OperateStatus> SaveOptionsToDictionary(SystemZeroCode systemZero)
        {
            OperateStatus operateStatus = new OperateStatus();
            if (systemZero.Type == EnumZeroCodeType.工作表.ToShort())
            {
                var columns = systemZero.ColumnJson.JsonStringToList<SystemWorkSheetTableFieldDetailInput>();
                foreach (var column in columns.Where(w => w.Type != "district"))
                {
                    if (column.Options.Options.Any())
                    {
                        var parentId = Guid.Parse(column.Options.Pid);
                        await _dictionaryLogic.Save(new SystemDictionary
                        {
                            DictionaryId = parentId,
                            Name = column.Label,
                            Remark = systemZero.Name
                        });
                        await _dictionaryLogic.DeleteAsync(d => d.ParentId == parentId);
                        foreach (var item in column.Options.Options)
                        {
                            await _dictionaryLogic.Save(new SystemDictionary
                            {
                                DictionaryId = Guid.Parse(item.Value),
                                Name = item.Label,
                                ParentName = column.Label,
                                Color = item.Color,
                                ParentId = parentId,
                                Remark = systemZero.Name
                            });
                        }
                    }
                }
            }

            return operateStatus;
        }
        /// <summary>
        /// 发布
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<OperateStatus> SettingJson(SystemZeroCode input)
        {
            return await UpdateAsync(u => u.ZeroCodeId == input.ZeroCodeId, new { SettingJson = input.SettingJson, UpdateTime = DateTime.Now });
        }

        /// <summary>
        /// 获取
        /// </summary>
        /// <param name="paging"></param>
        /// <returns></returns>
        public async Task<OperateStatus<PagedResults<SystemZeroCodeFindOutput>>> Find(SystemZeroCodeFindInput paging)
        {
            return OperateStatus<PagedResults<SystemZeroCodeFindOutput>>.Success(await _zeroCodeRepository.Find(paging));
        }

        /// <summary>
        /// 冻结
        /// </summary>
        /// <returns></returns>
        public async Task<OperateStatus> IsFreeze(IdInput input)
        {
            var data = await FindAsync(f => f.ZeroCodeId == input.Id);
            data.IsFreeze = !data.IsFreeze;
            return await UpdateAsync(data);
        }

        /// <summary>
        /// 获取
        /// </summary>
        /// <param name="paging"></param>
        /// <returns></returns>
        public async Task<OperateStatus<SystemZeroCodeFindByIdOutput>> FindById(IdInput input)
        {
            var data = await FindAsync(f => f.ZeroCodeId == input.Id);
            SystemZeroCodeFindByIdOutput output = data.MapTo<SystemZeroCode, SystemZeroCodeFindByIdOutput>();
            if (data.Type == EnumZeroCodeType.视图.ToShort())
            {
                var zeroCodeWorksheet = await FindAsync(f => f.Type == EnumZeroCodeType.工作表.ToShort() && f.MenuId == data.MenuId);
                if (zeroCodeWorksheet != null)
                {
                    //处理显示列(后期用户可能自己定义显示列及顺序)
                    output.ColumnJson = zeroCodeWorksheet.ColumnJson;
                    output.FormZeroCodeId = zeroCodeWorksheet.ZeroCodeId;
                    output.SettingJson = zeroCodeWorksheet.SettingJson;
                }
            }
            return OperateStatus<SystemZeroCodeFindByIdOutput>.Success(output);
        }
        /// <summary>
        /// 获取移动端首页
        /// </summary>
        /// <param name="paging"></param>
        /// <returns></returns>
        public async Task<OperateStatus<SystemZeroCode>> FindMobileConsole()
        {
            var data = await FindAsync(f => f.Type == 3 && f.IsDelete == false && f.IsFreeze == false);
            return OperateStatus<SystemZeroCode>.Success(data);
        }
        /// <summary>
        /// 获取
        /// </summary>
        /// <param name="paging"></param>
        /// <returns></returns>
        public async Task<OperateStatus<SystemZeroCode>> FindPublicJsonById(IdInput input, bool searchPublicJson = false)
        {
            SystemZeroCode zeroCode = new SystemZeroCode();
            using (var fix = new SqlDatabaseFixture())
            {
                if (searchPublicJson)
                {
                    zeroCode = await fix.Db.SystemZeroCode.SetSelect(s => new { s.MenuId, s.TableName, s.PublicJson }).FindAsync(f => f.ZeroCodeId == input.Id);
                }
                else
                {
                    zeroCode = await fix.Db.SystemZeroCode.SetSelect(s => new { s.MenuId, s.TableName }).FindAsync(f => f.ZeroCodeId == input.Id);
                }

                //得到关联表单设计
                var zeroCodeEdit = await fix.Db.SystemZeroCode.FindAsync(f => f.MenuId == zeroCode.MenuId && f.Type == EnumZeroCodeType.工作表.ToShort());
                zeroCode.TableName = zeroCodeEdit.TableName;
                zeroCode.ColumnJson = zeroCodeEdit.ColumnJson;
            }
            return OperateStatus<SystemZeroCode>.Success(zeroCode);
        }
        /// <summary>
        /// 获取
        /// </summary>
        /// <param name="paging"></param>
        /// <returns></returns>
        public async Task<OperateStatus<SystemZeroCode>> FindColumnJsonJsonById(IdInput input)
        {
            SystemZeroCode zeroCode = new SystemZeroCode();
            using (var fix = new SqlDatabaseFixture())
            {
                zeroCode = await fix.Db.SystemZeroCode.SetSelect(s => new { s.TableName, s.ColumnJson }).FindAsync(f => f.ZeroCodeId == input.Id);
            }
            return OperateStatus<SystemZeroCode>.Success(zeroCode);
        }

        /// <summary>
        /// 根据菜单获取
        /// </summary>
        /// <param name="paging"></param>
        /// <returns></returns>
        public async Task<OperateStatus<IEnumerable<SystemZeroCodeFindByMenuIdOutput>>> FindByMenuId(SystemZeroCodeFindByMenuIdInput input)
        {
            List<SystemZeroCodeFindByMenuIdOutput> outputs = new List<SystemZeroCodeFindByMenuIdOutput>();
            using (var fix = new SqlDatabaseFixture())
            {
                var zeroCode = await fix.Db.SystemZeroCode.SetSelect(s => new { s.TableName, s.ZeroCodeId, s.Name, s.Type, s.PublicJson }).FindAllAsync(f => f.MenuId == input.MenuId);
                if (input.Type == EnumZeroCodeType.视图.ToShort())
                {
                    foreach (var item in zeroCode.ToList().Where(w => w.Type == input.Type))
                    {
                        var viewJson = JsonConvert.DeserializeObject<SystemZeroCodeViewJsonOutput>(item.PublicJson);
                        SystemZeroCodeFindByMenuIdOutput findByMenuIdOutput = new SystemZeroCodeFindByMenuIdOutput()
                        {
                            ZeroCodeId = item.ZeroCodeId,
                            Name = item.Name,
                            Icon = viewJson.Icon,
                        };
                        outputs.Add(findByMenuIdOutput);
                    }
                }
                if (input.Type == EnumZeroCodeType.工作表.ToShort())
                {
                    var menu = await fix.Db.SystemMenu.SetSelect(s => new { s.Icon, s.Theme }).FindAsync(f => f.MenuId == input.MenuId);
                    foreach (var item in zeroCode.ToList().Where(w => w.Type == input.Type))
                    {
                        SystemZeroCodeFindByMenuIdOutput findByMenuIdOutput = new SystemZeroCodeFindByMenuIdOutput()
                        {
                            ZeroCodeId = item.ZeroCodeId,
                            Name = item.Name,
                            Icon = menu.Icon,
                            TableName = item.TableName,

                        };
                        outputs.Add(findByMenuIdOutput);
                    }
                }
            }
            return OperateStatus<IEnumerable<SystemZeroCodeFindByMenuIdOutput>>.Success(outputs);
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<OperateStatus> Delete(IdInput<string> input)
        {
            foreach (var id in input.Id.Split(','))
            {
                var ZeroCodeId = Guid.Parse(id);
                await DeleteAsync(u => u.ZeroCodeId == ZeroCodeId);
            }
            return OperateStatus.Success();
        }

        /// <summary>
        /// 获取基础配置信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<OperateStatus<IEnumerable<SystemZeroCodeFindBaseOutput>>> FindBase(SystemZeroCodeFindBaseInput input)
        {
            return OperateStatus<IEnumerable<SystemZeroCodeFindBaseOutput>>.Success(await _zeroCodeRepository.FindBase(input));
        }

        /// <summary>
        /// 获取基础配置信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<OperateStatus<SystemZeroCodeFindColumnJsonDataFromNameOutput>> FindColumnJsonByDataFromName(SystemZeroCodeFindColumnJsonDataFromNameInput input)
        {
            OperateStatus<SystemZeroCodeFindColumnJsonDataFromNameOutput> operateStatus = new OperateStatus<SystemZeroCodeFindColumnJsonDataFromNameOutput>();
            using (var fix = new SqlDatabaseFixture())
            {
                var config = await fix.Db.SystemZeroCode.SetSelect(s => new { s.ColumnJson, s.MenuId }).FindAsync(f => f.TableName == input.DataFromName && f.Type == EnumZeroCodeType.工作表.ToShort());
                if (config != null && config.ColumnJson.IsNotNullOrEmpty())
                {
                    operateStatus.Msg = "存在配置表";
                    operateStatus.Code = ResultCode.Success;
                    operateStatus.Data = new SystemZeroCodeFindColumnJsonDataFromNameOutput
                    {
                        ColumnJson = config.ColumnJson,
                        MenuId = config.MenuId
                    };
                    return operateStatus;
                }
            }
            operateStatus.Msg = "非配置表";
            return operateStatus;
        }

        /// <summary>
        /// 获取基础配置信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<OperateStatus<SystemZeroCodeFindColumnJsonByMenuIdOutput>> FindColumnJsonByMenuId(SystemZeroCodeFindColumnJsonByMenuIdInput input)
        {
            OperateStatus<SystemZeroCodeFindColumnJsonByMenuIdOutput> operateStatus = new OperateStatus<SystemZeroCodeFindColumnJsonByMenuIdOutput>();
            using (var fix = new SqlDatabaseFixture())
            {
                var config = await fix.Db.SystemZeroCode.SetSelect(s => new { s.ColumnJson, s.TableName }).FindAsync(f => f.MenuId == input.MenuId && f.Type == EnumZeroCodeType.工作表.ToShort());
                if (config != null && config.ColumnJson.IsNotNullOrEmpty())
                {
                    operateStatus.Msg = "存在配置表";
                    operateStatus.Code = ResultCode.Success;
                    operateStatus.Data = new SystemZeroCodeFindColumnJsonByMenuIdOutput
                    {
                        ColumnJson = config.ColumnJson,
                        TableName = config.TableName
                    };
                    return operateStatus;
                }
            }
            operateStatus.Msg = "非配置表";
            return operateStatus;
        }

        /// <summary>
        /// 根据关键词查询相关发布设计内容
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<OperateStatus<List<SystemZeroCodeFindByKeyOutput>>> Key(SystemZeroCodeFindByKeyInput input)
        {
            OperateStatus<List<SystemZeroCodeFindByKeyOutput>> operateStatus = new OperateStatus<List<SystemZeroCodeFindByKeyOutput>>();
            using (var fix = new SqlDatabaseFixture())
            {
                var data = await fix.Db.SystemZeroCode.SetSelect(s => new { s.MenuId, s.Name, s.Type, s.ZeroCodeId, s.Remark, s.IsFreeze, s.IsDelete, s.CreateTime, s.CreateUserName, s.UpdateTime, s.UpdateUserName }).FindAllAsync(f => f.PublicJson.Contains(input.Key));
                operateStatus.Code = ResultCode.Success;
                operateStatus.Msg = Chs.QuerySuccessful;
                operateStatus.Data = data.MapToList<SystemZeroCode, SystemZeroCodeFindByKeyOutput>();
                return operateStatus;
            }
        }
        /// <summary>
        /// 获取表单字段,若为第三方则检测表名字段是否具有,若有则读取对于的表字段
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<OperateStatus<List<SystemZeroCodeFindFormColumnsOutput>>> FindFormColumns(IdInput input)
        {
            List<SystemZeroCodeFindFormColumnsOutput> outputs = new List<SystemZeroCodeFindFormColumnsOutput>();
            var config = await FindAsync(f => f.ZeroCodeId == input.Id);
            if (config != null)
            {
                if (config.ColumnJson.IsNotNullOrEmpty())
                {
                    var columns = config.ColumnJson.JsonStringToList<SystemWorkSheetTableFieldDetailInput>();
                    foreach (var item in columns)
                    {
                        SystemZeroCodeFindFormColumnsOutput formColumnsOutput = new SystemZeroCodeFindFormColumnsOutput
                        {
                            Name = item.Model,
                            Description = item.Label,
                            Type = item.Type
                        };
                        outputs.Add(formColumnsOutput);
                    }
                    return OperateStatus<List<SystemZeroCodeFindFormColumnsOutput>>.Success(outputs);
                }
                //是否具有表名
                if (config.TableName.IsNotNullOrEmpty())
                {
                    var columns = await _dataBaseRepository.FindDataBaseColumns(new SystemDataBaseTableDto { Name = config.TableName });
                    foreach (var item in columns)
                    {
                        SystemZeroCodeFindFormColumnsOutput formColumnsOutput = new SystemZeroCodeFindFormColumnsOutput
                        {
                            Name = item.Name,
                            Description = item.Description,
                            Type = item.Type
                        };
                        outputs.Add(formColumnsOutput);
                    }
                }
            }

            return OperateStatus<List<SystemZeroCodeFindFormColumnsOutput>>.Success(outputs);
        }
        #endregion
    }
}